home *** CD-ROM | disk | FTP | other *** search
/ Mac-Source 1994 July / Mac-Source_July_1994.iso / C and C++ / Commun⁄Network / RevRdist Folder / RevRdist / RevRdist src / fileops.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-08-27  |  10.5 KB  |  459 lines  |  [TEXT/KAHL]

  1. /*
  2.  * fileops.c - routines for misc file/folder operations
  3.  */
  4. #include "RevRdist.h"
  5. #include "dispatch.h"
  6. #include "desktop.h"
  7. #include "TransSkelProto.h"
  8. #include "TransDisplayProto.h"
  9.  
  10. #define    CLSIZE(n)    ((n + ClientClpM) & ~ClientClpM)
  11.  
  12.  
  13. /*
  14.  *=========================================================================
  15.  * createFolder (name, vol, dir, ct) - create a folder
  16.  * entry:    name = string giving folder name
  17.  *            vol = ioVRefNum of volume to create folder in
  18.  *            dir = dirID name is relative to
  19.  *            ct = pointer to optional catalog node whose window information
  20.  *                will be copied to the new folder
  21.  *=========================================================================
  22.  */
  23. OSErr
  24. createFolder (name, vol, dir, ct)
  25.     StringPtr    name;
  26.     Integer        vol;
  27.     Longint        dir;
  28.     cnode_t *    ct;
  29. {
  30.     int                error;
  31.     HParamBlockRec    hpb;
  32.     CInfoPBRec        ci;
  33.  
  34.     error = 0;
  35.     ZERO (hpb);
  36.     hpb.fileParam.ioNamePtr = name;
  37.     hpb.fileParam.ioVRefNum = vol;
  38.     hpb.fileParam.ioDirID = dir;
  39.     error = PBDirCreate (&hpb, false);
  40.     if (error)
  41.     {
  42.         Clue1 = "\pPBDirCreate";
  43.         goto errexit;
  44.     }
  45.     if (ct)
  46.     {
  47.         ZERO (ci);
  48.         ci.dirInfo.ioVRefNum = vol;
  49.         ci.dirInfo.ioFDirIndex = -1;
  50.         ci.dirInfo.ioDrDirID = hpb.fileParam.ioDirID;
  51.         error = PBGetCatInfo (&ci, false);
  52.         if (error)
  53.         {
  54.             Clue1 = "\pPBGetCatInfo";
  55.             goto errexit;
  56.         }
  57.         ci.dirInfo.ioDrCrDat = ct->crDate;
  58.         ci.dirInfo.ioDrMdDat = ct->mdDate;
  59.         ci.dirInfo.ioDrUsrWds.frRect = ct->in.d.dinfo.frRect;
  60.         ci.dirInfo.ioDrUsrWds.frView = ct->in.d.dinfo.frView;
  61.         ci.dirInfo.ioDrFndrInfo.frScroll = ct->in.d.frScroll;
  62.         error = PBSetCatInfo (&ci, false);
  63.         if (error)
  64.         {
  65.             Clue1 = "\pPBSetCatInfo";
  66. errexit:
  67.             ClueID = error;
  68.             Clue0 = "\pcreateFolder";
  69.         }
  70.     }
  71.     return error;
  72. }
  73.  
  74.  
  75. /*
  76.  *=========================================================================
  77.  * discard (cp,flg) - delete file/folder from client
  78.  * entry:    cp = pointer to client catalog list node
  79.  *            flg = true to log the discard
  80.  *            ClientVol applies to catalog
  81.  * returns:    0 on success, else OSErr
  82.  *            ClientSp updated
  83.  *=========================================================================
  84.  */
  85. OSErr
  86. discard (cp, flg)
  87. register cnode_t *    cp;
  88. Boolean            flg;
  89. {
  90.     OSErr            error;
  91.     HParamBlockRec    pb;                    /* PBHDelete param block */
  92.  
  93.     if (flg)
  94.         notice (L_DISCARD, cp->name, nil);
  95.     if (Flags & PF_LISTONLY)
  96.         return 0;
  97.     /*
  98.      * If the file is locked, we need to unlock it first
  99.      */
  100.     if (cp->attrib & fLocked)
  101.         error = unlock (cp);
  102.     desktop_remove (cp);
  103.     ZERO (pb);
  104.     pb.fileParam.ioNamePtr = cp->name;
  105.     pb.fileParam.ioVRefNum = ClientVol;
  106.     pb.fileParam.ioDirID = cp->parID;
  107.     error = PBHDelete (&pb, false);
  108.     if (error == 0 && cp->ctype == C_FILE)
  109.     {
  110.         ClientSp += CLSIZE(cp->in.f.fileLen) + CLSIZE(cp->in.f.rsrcLen);
  111.     }
  112.     if (error && error != fnfErr)
  113.     {
  114.         ClueID = error;
  115.         if (flg)
  116.             notice (L_FILE, "\pdiscard", cp->name, nil);
  117.     }
  118.     else
  119.         if (flg)
  120.             statMsgClr ();
  121.     return error;
  122. }
  123.  
  124.  
  125.  
  126.  
  127. /*
  128.  *=========================================================================
  129.  * emptyFolder (ap, func) - empty client folder given by catalog list entry
  130.  * entry:    first param = pointer to catalog list node for client folder
  131.  *            second param = pointer to function to call for each entry
  132.  *                in folder to see if it should be deleted.
  133.  *                = nil to always delete
  134.  *            ClientVol = VRefNum of client volume
  135.  * returns:    0 if folder emptied, else <> 0
  136.  *=========================================================================
  137.  */
  138. DISPATCHED (emptyFolder)
  139. {
  140.     struct    lm
  141.     {
  142.         frame_t            f;
  143.         cnode_t *        ap;            /* copy of first arg */
  144.         iProcPtr        func;        /* copy of second arg */
  145.         cnode_t *        fp;            /* head of catalog list for folder */
  146.         cnode_t *        cp;            /* ptr to current entry in fp */
  147.         Boolean            rej;        /* true once filter rejects */
  148.     };
  149.     typedef struct lm    lm_t;
  150.     register lm_t *        m;
  151.     register cnode_t *    cp;            /* working copy of m->cp */
  152.     OSErr                error;
  153.     Ptr                    paramv[2];
  154.     short                result;
  155.  
  156.     m = *(lm_t **)fh;
  157.     result = request;
  158.     error = 0;
  159.     switch (request)
  160.     {
  161.     case R_INIT:
  162.         if (ClueID = resizeFrame (fh, sizeof (lm_t)))
  163.             return R_ERROR;
  164.         m = *(lm_t **)fh;
  165.         m->ap = (cnode_t *)argv[0];
  166.         m->func = (iProcPtr)argv[1];
  167.         m->f.state = 1;
  168.         return R_CONT;
  169.  
  170.     case R_CONT:
  171.         switch (m->f.state)
  172.         {
  173.         case 1:
  174.             notice (L_DOEMPTY, m->ap->name, nil);
  175.             if (m->ap->attrib & fLocked)
  176.             {
  177.                 if (error = unlock (m->ap))
  178.                 {
  179.                     m->rej = true;
  180.                     paramv[0] = (Ptr)&m->rej;
  181.                     return (popCall (R_CONT, paramv));
  182.                 }
  183.             }
  184.             cp = listFolder (ClientVol, m->ap->dirID);
  185.             if (cp == nil)
  186.             {
  187.                 paramv[0] = 0;
  188.                 return (popCall (R_CONT, paramv));
  189.             }
  190.             m->fp = m->cp = cp;
  191.             m->f.state = 2;
  192.             return R_CONT;
  193.         case 2:
  194.             /*
  195.              * For each iteration in state 2, we discard one entry,
  196.              * either a file or a folder
  197.              */
  198.             cp = m->cp;
  199.             if (!cp)
  200.                 break;                /* done with folder, exit */
  201.             m->cp = cp->link;        /* assume will go on */
  202.             if (m->func && !(*m->func)(cp))
  203.             {
  204.                 m->rej = true;        /* if filter rejects entry */
  205.                 return R_CONT;
  206.             }
  207.             if (cp->ctype == C_FOLDER)
  208.             {
  209.                 /*
  210.                  * Use ourselves to empty a folder
  211.                  */
  212.                 m->cp = cp;            /* back up to us again */
  213.                 m->f.state = 3;
  214.                 paramv[0] = (Ptr) cp;
  215.                 paramv[1] = (Ptr) m->func;
  216.                 result = pushCall (emptyFolder, paramv);
  217.                 if (result == R_CONT)
  218.                     Depth++;
  219.                 return result;
  220.             }
  221.             error = discard(cp, true);
  222.             if (error && error != fnfErr)
  223.                 m->rej = true;
  224.             return R_CONT;
  225.         case 3:
  226.             /*
  227.              * Here after folder emptied
  228.              */
  229.             Depth--;
  230.             cp = m->cp;
  231.             m->cp = cp->link;
  232.             m->f.state = 2;
  233.             if (argv && argv[0] && *(Boolean *)argv[0])
  234.                 m->rej = true;    /* folder could not be emptied */
  235.             else
  236.             {
  237.                 if ((error = discard (cp, true)) && error != fnfErr)
  238.                     m->rej = true;
  239.             }
  240.             return R_CONT;
  241.         } /* end of R_CONT state switch */
  242.         break;
  243.     /*
  244.      * R_QUIT and R_BACKOUT just fall through
  245.      */
  246.     }
  247.     paramv[0] = nil;
  248.     if (GetHandleSize ((Handle)fh) >= sizeof (lm_t))
  249.     {
  250.         freeList (m->fp);
  251.         paramv[0] = (Ptr)&m->rej;
  252.     }
  253.     statMsgClr ();
  254.     return (popCall (result, paramv));
  255. }
  256.  
  257.  
  258.  
  259. /*
  260.  *=========================================================================
  261.  * relock (cp) - set the finder locked bit on a client file/folder
  262.  * entry:    cp = pointer to catalog list entry for file/folder
  263.  *            ClientVol set
  264.  * returns:    OSErr
  265.  *=========================================================================
  266.  */
  267. OSErr
  268. relock (cp)
  269. register cnode_t *    cp;
  270. {
  271.     HParamBlockRec    pb;
  272.     OSErr        error;
  273.  
  274.     ZERO (pb);
  275.     pb.fileParam.ioNamePtr = cp->name;
  276.     pb.fileParam.ioVRefNum = ClientVol;
  277.     pb.fileParam.ioDirID = cp->parID;
  278.     error = PBHSetFLock (&pb, false);
  279.     if (error && error != fnfErr)
  280.     {
  281.         Clue1 = "\pPBHSetFLock";
  282.         Clue0 = (SP) "relock";
  283.         return error;
  284.     }
  285.     cp->attrib |= fLocked;
  286.     return error;
  287. }
  288.  
  289.  
  290.  
  291. /*
  292.  *=========================================================================
  293.  * touch (vol, cp) - set modification time of file to now
  294.  * entry:    vol = vRefNum of file
  295.  *            cp = pointer to catalog list entry for file/folder
  296.  * returns:    OSErr
  297.  *=========================================================================
  298.  */
  299. OSErr
  300. touch (Integer vol, cnode_t *cp)
  301. {
  302.     CInfoPBRec            ci;
  303.     OSErr                error;
  304.     unsigned long        now;
  305.     Str255                s;
  306.  
  307.     if (cp->name[0] == 0 || cp->parID == 0)
  308.         return 0;
  309.     ZERO (ci);
  310.     COPYPS (cp->name, s);
  311.     ci.hFileInfo.ioNamePtr = s;
  312.     ci.hFileInfo.ioVRefNum = vol;
  313.     ci.hFileInfo.ioDirID = cp->parID;
  314.     Clue1 = "\pPBGetCatInfo";
  315.     error = PBGetCatInfo (&ci, false);
  316.     GetDateTime(&now);
  317.     if (error == 0 && now > ci.hFileInfo.ioFlMdDat)
  318.     {
  319.         if ((ci.hFileInfo.ioFlAttrib & ioDirMask) == 0)
  320.         {
  321.             ci.hFileInfo.ioDirID = cp->parID;
  322.             ci.hFileInfo.ioFDirIndex = 0;
  323.         }
  324.         ci.hFileInfo.ioFlMdDat = now;
  325.         Clue1 = "\pPBSetCatInfo";
  326.         error = PBSetCatInfo (&ci, false);
  327.     }
  328.     return error;
  329. }
  330.  
  331.  
  332.  
  333.  
  334. /*
  335.  *=========================================================================
  336.  * unlock (cp) - clear the finder locked bit on a client file/folder
  337.  * entry:    cp = pointer to catalog list entry for file/folder
  338.  *            ClientVol set
  339.  * returns:    OSErr
  340.  *=========================================================================
  341.  */
  342. OSErr
  343. unlock (cp)
  344. register cnode_t *    cp;
  345. {
  346.     HParamBlockRec    pb;
  347.     OSErr        error;
  348.  
  349.     ZERO (pb);
  350.     pb.fileParam.ioNamePtr = cp->name;
  351.     pb.fileParam.ioVRefNum = ClientVol;
  352.     pb.fileParam.ioDirID = cp->parID;
  353.     error = PBHRstFLock (&pb, false);
  354.     if (error && error != fnfErr)
  355.     {
  356.         Clue1 = "\pPBHRstFLock";
  357.         Clue0 = (SP) "unlock";
  358.         return error;
  359.     }
  360.     cp->attrib &= ~fLocked;
  361.     return error;
  362. }
  363.  
  364.  
  365. /*
  366.  *=========================================================================
  367.  * verifyBlessed () - check client "Blessed" folder
  368.  * entry:    ClientVol set
  369.  *=========================================================================
  370.  */
  371. void
  372. verifyBlessed ()
  373. {
  374.     OSErr            error;
  375.     Longint            dirID;            /* dir ID of blessed folder */
  376.     CInfoPBRec        ci;                /* for PBGetCatInfo */
  377.     HParamBlockRec    pb;                /* for PBHGetVInfo */
  378.     Str255            fs, vs;            /* file and volume name strings */
  379.  
  380.     /*
  381.      * Get info about client volume.
  382.      */
  383.     Clue0 = "\pverifyBlessed";
  384.     ZERO (pb);
  385.     vs[0] = 0;
  386.     pb.volumeParam.ioNamePtr = vs;
  387.     pb.volumeParam.ioVRefNum = ClientVol;
  388.     pb.volumeParam.ioVolIndex = -1;
  389.     Clue1 = "\pPBHGetVInfo";
  390.     if (error = PBHGetVInfo (&pb, false))
  391.         goto syserr;
  392.     dirID = pb.volumeParam.ioVFndrInfo[0];
  393.     if (dirID == 0)
  394.     {
  395.         /*
  396.          * No blessed folder set yet.  See if there is one with right name
  397.          */
  398.         fs[0] = 0;
  399.         GetIndString (fs, NAME_STR, NAME_FOLDER);
  400.         if (fs[0] == 0)
  401.             return;
  402.         ZERO (ci);
  403.         ci.dirInfo.ioNamePtr = fs;
  404.         ci.dirInfo.ioVRefNum = ClientVol;
  405.         Clue1 = "\pPBGetCatInfo";
  406.         if (error = PBGetCatInfo (&ci, false))
  407.             goto cantboot;
  408.         dirID = ci.dirInfo.ioDrDirID;
  409.         /*
  410.          * Make it the Blessed folder, which may be presumptuous
  411.          */
  412.         if (Flags & PF_VERBOSE)
  413.             notice (L_BLESSED, nil);
  414.         if ((Flags & PF_LISTONLY) == 0)
  415.         {
  416.             pb.volumeParam.ioVFndrInfo[0] = dirID;
  417.             pb.volumeParam.ioVFndrInfo[1] = dirID;
  418.             pb.volumeParam.ioNamePtr = 0;
  419.             Clue1 = "\pPBSetVInfo";
  420.             if (error = PBSetVInfo (&pb, false))
  421.                 goto syserr;
  422.         }
  423.     }
  424.     /*
  425.      * Check Blessed folder for System file and Finder
  426.      */
  427.     fs[0] = 0;
  428.     GetIndString (fs, NAME_STR, NAME_SYSTEM);
  429.     if (fs[0] == 0)
  430.         return;
  431.     ZERO (ci);
  432.     ci.hFileInfo.ioNamePtr = fs;
  433.     ci.hFileInfo.ioVRefNum = ClientVol;
  434.     ci.hFileInfo.ioDirID = dirID;
  435.     Clue1 = "\pPBGetCatInfo";
  436.     if (error = PBGetCatInfo (&ci, false))
  437.         goto cantboot;
  438.     fs[0] = 0;
  439.     GetIndString (fs, NAME_STR, NAME_FINDER);
  440.     if (fs[0] == 0)
  441.         return;
  442.     ci.hFileInfo.ioDirID = dirID;
  443.     ci.hFileInfo.ioFDirIndex = 0;
  444.     if (error = PBGetCatInfo (&ci, false))
  445.         goto cantboot;
  446.     pb.volumeParam.ioNamePtr = 0;
  447.     (void) PBFlushVol ((ParmBlkPtr)&pb, false);
  448.     return;
  449.  
  450. cantboot:
  451.     if (error == fnfErr)
  452.     {
  453.         notice (L_BADBLESSED, vs, fs, nil);
  454.         return;
  455.     }
  456. syserr:
  457.     ClueID = error;
  458.     panic (true, E_SYS, nil);
  459. }